import { resolve } from 'node:path'
import { defineConfig } from 'vite'
import { type GetManualChunk, type GetModuleInfo } from 'rollup'
import createPlugins from './vite'

const assetFileNames = (assetInfo: any) => {
  const imageReg = /\.(jpe?g|png|gif|svg)$/i
  const fontReg = /\.(ttf|woff|woff2|eot)$/i
  // 设置不同类型文件的输出路径及命名规则
  if (assetInfo.type === 'asset') {
    if (imageReg.test(assetInfo.name)) {
      return 'img/[name].[hash].[ext]' // 图像文件输出路径及命名规则
    }
    if (fontReg.test(assetInfo.name)) {
      return 'fonts/[name].[hash].[ext]' // 字体文件输出路径及命名规则
    }
  }
  return '[ext]/[name]-[hash].[ext]' // 其他资源文件输出路径及命名规则
}

const makeChuckModules = (id: string, getModuleInfo: GetModuleInfo) => {
  const dependentEntryPoints: string[] = []
  const baseInfo = getModuleInfo(id)
  if (baseInfo) {
    // 在这里，我们使用 Set 一次性处理每个依赖模块
    // 它可以阻止循环依赖中的无限循环
    const idsToHandle = new Set<string>(baseInfo.dynamicImporters)
    for (const moduleId of idsToHandle) {
      const info = getModuleInfo(moduleId)
      if (info) {
        if (info.isEntry || info.dynamicImporters.length > 0) {
          dependentEntryPoints.push(moduleId)
        }
        // Set 迭代器足够智能，可以处理
        // 在迭代过程中添加元素
        for (const importerId of info.importers) idsToHandle.add(importerId)
      }
    }

    // 如果仅有一个入口，那么我们会根据入口名
    // 将它放到独立的 chunk 中
    if (dependentEntryPoints.length === 1) {
      return dependentEntryPoints.length
    }
    // // 对于多个入口，我们会把它放到“共享”的 chunk 中
    // if (dependentEntryPoints.length > 1) {
    // }
  }
  return dependentEntryPoints.length
}
const chuckCodemirror = (id: string, getModuleInfo: GetModuleInfo) => {
  let chuckName = ''
  const match = /@codemirror\+(.*?)@/.exec(id)
  if (match && match[1]) {
    const depsLength = makeChuckModules(id, getModuleInfo)
    if (depsLength >= 1) {
      chuckName = `codemirror/${match[1]}`
    }
    // if (depsLength === 1){
    //   // 如果仅有一个入口，那么我们会根据入口名
    //   chuckName = `codemirror/${match[1]}`;
    // }
    // if (depsLength > 1){
    //   // 对于多个入口，我们会把它放到“共享”的 chunk 中
    //   chuckName = `codemirror-${match[1]}`;
    // }
  }
  return chuckName
}

const manualChunks: GetManualChunk = function (id: string, { getModuleInfo }) {
  const chuckCodemirrorName = chuckCodemirror(id, getModuleInfo)
  if (chuckCodemirrorName) return chuckCodemirrorName
}

export default defineConfig(async configEnv => {
  return {
    base: './',
    define: {
      process: {
        env: configEnv,
      },
    },
    resolve: {
      alias: {
        '@': resolve(process.cwd(), 'src'),
      },
    },
    css: {
      preprocessorOptions: {
        sass: {
          additionalData: `@use "@/styles/scss/global.scss" as *;`,
        },
      },
    },
    server: {
      open: true,
      host: true,
    },
    plugins: await createPlugins(configEnv),
    optimizeDeps: {
      // include:["systemjs/dist/system-node.cjs"]
    },
    build: {
      manifest: 'manifest.json',
      rollupOptions: {
        input: resolve(process.cwd(), 'index.html'),
        output: {
          // globals: globals,
          entryFileNames: '[name]-[hash].js', // 指定 JS 文件的输出路径及命名规则
          chunkFileNames: 'js/[name]-[hash].js', // 指定分片文件的输出路径及命名规则
          assetFileNames,
          manualChunks,
        },
      },
    },
  }
})
